#include <iostream>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <linux/input.h>
#include <cstdlib>
#include <sys/select.h>
using namespace std;

typedef enum
{
    NONE,
    UP,
    DOWN,
    LEFT,
    RIGHT
} TouchDirection;

typedef enum
{
    NONE_CLICK,   // 无点击
    SINGLE_CLICK, // 单击
    DOUBLE_CLICK, // 双击
    SLIDE         // 滑动
} TouchType;

class TouchPad
{
public:
    FILE *fp_touch;

    int touch_init()
    {
        fp_touch = fopen("/dev/input/event0", "r");
        if (fp_touch == NULL)
        {
            perror("touch_fopen");
            return -1;
        }
        cout << "open touch success" << endl;
        return 0;
    }

    void touch_exit()
    {
        fclose(fp_touch);
        cout << "close touch success" << endl;
    }

    void get_touch_gesture(FILE *fp_touch, int &direction, int &touch_type)
    {
        int sx = -1, sy = -1, ex = -1, ey = -1;
        struct input_event buf;
        int isPressDown = 0; // 是否按下

        while (1)
        {
            memset(&buf, 0, sizeof(buf));

            // 非阻塞读取
            if (fread(&buf, sizeof(buf), 1, fp_touch) != 1)
            {
                direction = NONE;
            }

            // 坐标开始变化
            if (buf.type == EV_ABS)
            {
                if (isPressDown == 0)
                {
                    if (buf.code == ABS_X)
                    {
                        sx = buf.value * 800;
                    }
                    if (buf.code == ABS_Y)
                    {
                        sy = buf.value * 480;
                    }
                }
                else
                {
                    if (buf.code == ABS_X)
                    {
                        ex = buf.value * 800;
                    }
                    if (buf.code == ABS_Y)
                    {
                        ey = buf.value * 480;
                    }
                }
            }

            // 触摸动作开始（手指按下） 或触摸动作结束（手指松开）
            if (buf.type == EV_KEY && buf.code == BTN_TOUCH)
            {
                if (buf.value == 1)
                { // 按下
                    isPressDown = 1;
                    if (sx > 0 && sx < 200)
                    {
                        touch_type = SINGLE_CLICK;
                        direction = LEFT;
                        return;
                    }
                    if (sx > 600 && sx < 800)
                    {
                        touch_type = SINGLE_CLICK;
                        direction = RIGHT;
                        return;
                    }
                }
                else
                { // 松开
                    isPressDown = 0;

                    if (ex != -1 && ey != -1 && abs(sx - ex) > 100)
                    {
                        touch_type = SLIDE;
                        direction = sx > ex ? LEFT : RIGHT;
                    }
                    else if (sy != -1 && ey != -1 && abs(sy - ey) > 100)
                    {
                        touch_type = SLIDE;
                        direction = sy > ey ? UP : DOWN;
                    }
                    else
                    {
                        touch_type = SLIDE;
                        direction = NONE;
                    }
                    return;
                }
            }
        }
    }
};

void print_gesture(int &direction, int &touch_type)
{
    printf("direction = %d, touch_type = %d\n", direction, touch_type);
    if (touch_type == SINGLE_CLICK)
    {
        cout << "single click" << endl;
    }
    else if (touch_type == SLIDE)
    {
        if (direction == LEFT)
        {
            cout << "slide left" << endl;
        }
        else if (direction == RIGHT)
        {
            cout << "slide right" << endl;
        }
        else if (direction == UP)
        {
            cout << "slide up" << endl;
        }
        else if (direction == DOWN)
        {
            cout << "slide down" << endl;
        }
    }
}

int main()
{
    TouchPad tp;
    tp.touch_init();

    int direction;
    int touch_type;
    int &direction_ref = direction;
    int &touch_type_ref = touch_type;
    while (1)
    {
        tp.get_touch_gesture(tp.fp_touch, direction_ref, touch_type_ref);
        print_gesture(direction_ref, touch_type_ref);
    }
    return 0;
}